/*
 * This file is part of LexiToolsMobile
 *  
 * Author: Jerzy Wawro
 * ver. 1.00
 * Copyright: Tenar (http://www.tenar.pl)
 *
 * Mobile LexiTools is an open source project; you can redistribute it 
 * and/or modify it under the terms of the license as published -  GPL with 
 * the following modification:  fragments of the code may be not copyleft 
 * (hidden), to protect contents of the dicionaries.
 * In this case the author of non-public fragments of the code is obliged 
 * to make available functionally equivalent code for unprotected dictionaries.
 * 
 * Mobile LexiTools is distributed WITHOUT ANY WARRANTY.
 * See the license for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with LexiToolsMobile (see: gpl.txt); if not - you can find it 
 * on web page http://www.fsf.org/, or write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package dict;

class dPage {
  cache pgcache;
  byte[] buffer = new byte[pgfile.PAGESIZE];
  pgfile dtpgf;
  std_decoder decoder;
  
  public dPage( cache p_cache, pgfile pgf, std_decoder pdecoder ) {
      pgcache = p_cache;
      dtpgf = pgf;
      decoder = pdecoder;
  }
  
  void GetPage(short pgref)
  {
      buffer = pgcache.getpage(dtpgf,pgref).buffer;
  }
  
  String  getpstr_l0(byte ix2)
  {
    int i,x;
	
    x=0;
    for (i=ix2-1; i>0; i--) {
        if (buffer[x]<0) { 
           x=x+1+256+buffer[x];
        }
        else { 
           x=x+1+(int)buffer[x];
	}
    }
    decoder.l1decode(buffer, x);
    return new String(decoder.result, 0, decoder.lenght);
  }

String getpstr_l1(byte ix2)
  {
    int i,x;
	
    x=0;
    for (i=ix2-1; i>0; i--) {
        if (buffer[x]<0) { 
           x=x+1+256+buffer[x];
        }
        else { 
           x=x+1+(int)buffer[x];
	}
    }
    decoder.l2decode(buffer, x);
    return new String(decoder.result, 0, decoder.lenght);
  }
}

public final class std_dict{

 dict.pgfile ix0pgf;
 dict.btree ix0;
 dict.pgfile ix1pgf;
 dict.btree ix1;
 dict.pgfile dtpgf;
 dict.std_decoder decoder;
 dPage dic;

 String sKey4;
 String sKey;
 iResult w = new iResult(null, 0, (byte)0);
 iResult wn = new iResult(null, 0, (byte)0);
 
 static final int max_back=3100;
 static final int max_next=5000;
 int korekta = 0;
 
 /** Constructor. */
public std_dict(String dir, String dictfn, String ix0fn, short iroot0, String ix1fn, short iroot1)
   {
    int iType = 0;
    
    if (dir.startsWith("file:")) {
        iType=1;
    }
               
           ix0pgf = new dict.pgfile(iType, ix0fn, dir);
           ix0 = new dict.btree(ix0pgf, iroot0);
           ix1pgf = new dict.pgfile(iType, ix1fn, dir);
           ix1 = new dict.btree(ix1pgf, iroot1);

           dtpgf= new dict.pgfile(iType,dictfn,dir);
           decoder = new dict.std_decoder();
           dic = new dPage( ix0.memcache, dtpgf, decoder );
           if (dictfn.compareTo("tas")==0) {
               korekta=0;
           }
           else {
               korekta=0;
           }
}

String str0(iResult w)
{
  if (w==null) { return ""; }
  if (w.ptr1==0) { return ""; }
  dic.GetPage((short)(w.ptr1+korekta)); // ptr1?? zamiast ptr1+1 - blad w generowaniu?
  return dic.getpstr_l0((byte)w.ptr2); 
}

String str1(iResult w)
{
  if (w==null) { return ""; }
  if (w.ptr1==0) { return ""; }
  dic.GetPage((short)(w.ptr1+korekta)); // j.w.
  return dic.getpstr_l1((byte)(w.ptr2+1));
}


String str_eq(int l, iResult w)
{
  dic.GetPage((short)(w.ptr1+korekta));
  if (l==0)  return dic.getpstr_l0((byte)w.ptr2)+" : "+dic.getpstr_l1((byte)(w.ptr2+1));
  else   return dic.getpstr_l1((byte)(w.ptr2+1))+" : "+dic.getpstr_l0((byte)(w.ptr2));
}

int match(String s, String key, boolean k4) {
    int i;
    String k;
	
	if ((key==null) || (s==null)) { return -1; }
    if (key.length()>4) i=4;
    else i=key.length();
    if (k4) k=key.substring(0,i);
    else k=key;
    i=s.indexOf(k);
    if (i!=0) {
        i=s.indexOf(" "+k);
    }
    if (i<0) {
        i=s.indexOf("."+k);
    }
    if (i<0) {
        i=s.indexOf("-"+k);
    }
    if (i<0) {
        i=s.indexOf("("+k);
    }
    if (i<0) {
        i=s.indexOf(";"+k);
    }
    if (i<0) {
        i=s.indexOf("["+k);
    }
    if (i<0) {
        i=s.indexOf(","+k);
    }
return i;
}

public String FindFirst_l0_old(String key, boolean eq, boolean exactly) {

 String sKey_a;
 int c;
 boolean ok;
 boolean found;
 int bk;
 
 if (eq) bk=500;
 else bk=100;
 sKey=key;
 if (key.length()<4) sKey4=key;
 else sKey4=key.substring(0,4);
 ok=ix0.findkey(sKey4, w);
 if ((!ok) &&  exactly){
     return "";
 }
 if (ok) {
   sKey_a=str0(w);
   ok=ix0.prevkey(wn);
   if ( !ok ) {
      found=false;
   } else {
       found=true;
       c=0;
       do {
         if (match(sKey_a, sKey4,true)>=0) {
           c++;
           w.setKey(wn.key);w.ptr1=wn.ptr1;w.ptr2=wn.ptr2;
           ok=ix0.prevkey(wn);
           if (ok) sKey_a=str0(wn);
           else found=false;
           if (match(sKey_a, sKey4,true)<0) ok=false;
         }
         else found=false;
       } while ((found) && (c<bk));
   }
   if (!found) {
     ok=ix0.nextkey(wn);
     sKey_a=str0(wn);
   }
 }
 else {
    sKey_a=str0(w);
    wn.setKey(w.key);wn.ptr1=w.ptr1;wn.ptr2=w.ptr2;
 }
 c=0;
 while (ok && (match(sKey_a, sKey, false)<0) && (c<bk)) {
    c+=1;
    ok=ix0.nextkey(wn);
    if (ok) {
        sKey_a=str0(wn);
        w.setKey(wn.key);w.ptr1=wn.ptr1;w.ptr2=wn.ptr2;
    }
 }
 if (c>=2*bk) return "";
 else {
    if (eq) return str_eq(0,w);
    else  return sKey_a;
 }
}

public String FindFirst_l0(String key, boolean eq, boolean exactly) {

 String sKey_a;
 int c;
 boolean ok;
 int bk;
 
 sKey=key;
 if (key.length()<4) sKey4=key;
 else sKey4=key.substring(0,4);
 ok=ix0.findkey(key, w);
 if ((!ok) &&  exactly){
     return "";
 }
 if (ok) {
    bk=0;
    // find first
    do {
           ok=ix0.prevkey(wn);
           bk++;
    } while (ok && (bk<max_back) && (wn.key[0]==w.key[0])&& (wn.key[1]==w.key[1])
            && (wn.key[2]==w.key[2])&& (wn.key[3]==w.key[3]) );
//            && (exactly || (bk<max_back)) );
    if (ok && (bk<max_back)) ix0.nextkey(wn);
    sKey_a=str0(wn);
    w.setKey(wn.key);w.ptr1=wn.ptr1;w.ptr2=wn.ptr2;
  }
 else {
     bk=0;
     sKey_a=str0(w);
 }
 c=0;
 while (ok && (match(sKey_a, sKey, false)<0) && (c<max_next )) {
    c+=1;
    if (c==652) {
        c=653;
    }    
    ok=ix0.nextkey(w) && (wn.key[0]==w.key[0]) && (wn.key[1]==w.key[1])&&
            (wn.key[2]==w.key[2]) && (wn.key[3]==w.key[3]);
    if (ok) {
        sKey_a=str0(w);
    }
 }
 if ((c>=max_next) || !ok) return "";
 else {
    if (eq) return str_eq(0,w);
    else  return sKey_a;
 }
}

public String FindNext_l0(boolean eq) {
 String sKey_a;
 int c;
 boolean ok;
 boolean found;
 int sk;
 
 if (eq) sk=50;
 else sk=20;
 c=0;
 ok=ix0.nextkey(wn);
 sKey_a=str0(wn);
 found=false;
 while ((!found) && ok && (match(sKey_a, sKey4, true)>=0) && (c<sk)) {
     if (match(sKey_a, sKey, false)>=0) found=true;
     else {
        c+=1;
        ok=ix0.nextkey(wn);
        if (wn != null) sKey_a=str0(wn);
     }
 }
 if (!found) {
     return "";
 }
 else {
    if (eq) return str_eq(0,wn);
    else  return sKey_a;
 }
}


public String FindFirst_l1(String key, boolean eq, boolean exactly) {
 String sKey_a;
 int c;
 boolean ok;
 int bk;
 
 sKey=key;
 if (key.length()<4) sKey4=key;
 else sKey4=key.substring(0,4);
 ok=ix1.findkey(key, w);
 if ((!ok) &&  exactly){
     return "";
 }
 if (ok) {
    bk=0;
    // find first
    do {
           ok=ix1.prevkey(wn);
           bk++;
    } while (ok && (bk<max_back) && (wn.key[0]==w.key[0])&& (wn.key[1]==w.key[1])
            && (wn.key[2]==w.key[2])&& (wn.key[3]==w.key[3]) );
//            && (exactly || (bk<max_back)) );
    if (ok && (bk<max_back)) ix1.nextkey(wn);
    sKey_a=str1(wn);
    w.setKey(wn.key);w.ptr1=wn.ptr1;w.ptr2=wn.ptr2;
  }
 else {
     bk=0;
     sKey_a=str1(w);
 }
 c=0;
 while (ok && (match(sKey_a, sKey, false)<0) && (c<max_next )) {
    c+=1;
    ok=ix1.nextkey(w) && (wn.key[0]==w.key[0]) && (wn.key[1]==w.key[1])&&
            (wn.key[2]==w.key[2]) && (wn.key[3]==w.key[3]);
    if (ok) {
        sKey_a=str1(w);
    }
 }
 if ((c>=max_next) || !ok) return "";
 else {
    if (eq) return str_eq(1,w);
    else  return sKey_a;
 }
}

public String FindNext_l1(boolean eq) {
 String sKey_a;
 int c;
 boolean ok;
 boolean found;
 int sk;
 
 if (eq) sk=50;
 else sk=20;
 c=0;
 ok=ix1.nextkey(wn);
 sKey_a=str1(wn);
 found=false;
 while ((!found) && ok && (match(sKey_a, sKey4, true)>=0) && (c<sk)) {
     if (match(sKey_a, sKey, false)>=0) found=true;
     else {
        c+=1;
        ok=ix1.nextkey(wn);
        if (wn != null) sKey_a=str1(wn);
     }
 }
 if (!found) {
     return "";
 }
 else {
    if (eq) return str_eq(1,wn);
    else  return sKey_a;
 }
}



}

